package cn.csg.ams.collect2.poptopics.service.impl;

import cn.csg.ams.collect2.poptopics.dao.MkPrPfOutageEventDetailDao;
import cn.csg.ams.collect2.poptopics.dao.MkPrPfOutageRecoveryMonDao;
import cn.csg.ams.collect2.poptopics.datahub.TupleRecordDataUtils;
import cn.csg.ams.collect2.poptopics.entity.RecordInfo;
import cn.csg.ams.collect2.poptopics.entity.vo.MkPrPfOutageEventDetailVO;
import cn.csg.ams.collect2.poptopics.entity.vo.MkPrPfOutageRecoveryMonVO;
import cn.csg.ams.collect2.poptopics.infrastructure.constant.UserCategoryConstant;
import cn.csg.ams.collect2.poptopics.service.MkPrPfOutageEventDetailService;
import cn.csg.ams.collect2.poptopics.infrastructure.utils.DateUtil;
import com.aliyun.datahub.client.model.TupleRecordData;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;

/**
 * @author: zhanggang
 * @ClassName: MkPrPfOutageEventDetailServiceImpl
 * @date: 2023-11-17 09:06:54
 * @Description: 停电事件明细（flink计算出来的数据基表）(mk_pr_pf_outage_event_detail)表服务实现类
 */
@Service("mkPrPfOutageEventDetailService")
public class MkPrPfOutageEventDetailServiceImpl implements MkPrPfOutageEventDetailService {

    @Autowired
    private MkPrPfOutageEventDetailDao mkPrPfOutageEventDetailDao;

    @Autowired
    private MkPrPfOutageRecoveryMonDao outageRecoveryMonDao;

    // @Autowired
    // private KafkaProducer<String, String> kafkaProducer;


    /**
     * 插入停电事件
     *
     * @param data       告警消息
     * @param recordInfo 档案信息
     * @param eventId    停电事件id
     * @param startTimes 研判开始时间
     * @param judgeRule  研判规则
     * @return 影响行数
     */
    @Override
    public void saveOutageEvent(TupleRecordData data, RecordInfo recordInfo, String eventId, Long startTimes, String judgeRule) {
        // 运行电能表标识
        String runMeterId = TupleRecordDataUtils.getStringField(data, 2);
        // 告警标识
        String alarmId = TupleRecordDataUtils.getStringField(data, 0);
        // 告警时间
        String alarmTime = TupleRecordDataUtils.getStringField(data, 23);
        // 前置接受告警时间
        String preReceTime = TupleRecordDataUtils.getStringField(data, 22);

        // 2.创建停电事件
        MkPrPfOutageEventDetailVO outageEvent = new MkPrPfOutageEventDetailVO();
        // 数据id （告警标识）
        outageEvent.setDataId(alarmId);
        // 事件id
        outageEvent.setOutageEventId(eventId);
        // 对象类型， 对象id， 对象名称
        setObjIdAndName(outageEvent, recordInfo, runMeterId);
        // 数据时间
        outageEvent.setDataTime(new SimpleDateFormat("yyyyMMddHHmmss").format(new Date()));
        // 停电状态 (1-停电, 2-复电)
        outageEvent.setOutageStatus("1");
        // 停电开始时间
        outageEvent.setOutageStartTime(alarmTime);
        // 是否接受到告警 （1 未接收到停电告警 2接收到停电告警）
        outageEvent.setOutageAlarmState(2L);
        // 研判类型 (1-告警研判， 2-负荷研判)
        outageEvent.setJudgeType("1");
        // 研判规则
        outageEvent.setJudgeRule(judgeRule);
        // 分区
        outageEvent.setDs(alarmTime == null ? null : alarmTime.substring(0, 6));
        // 主站接收到数据时间
        outageEvent.setPrepositionTime(preReceTime);
        // 研判开始时间
        outageEvent.setStartTimes(startTimes);
        // 研判结束时间
        outageEvent.setEndTimes(System.currentTimeMillis());

        // 3.插入停电事件
        mkPrPfOutageEventDetailDao.insertMkPrPfOutageEventDetail(outageEvent);
    }


    /**
     * 根据对象类型（用户类型）设置objType、objId、objName
     */
    private void setObjIdAndName(MkPrPfOutageEventDetailVO outageEvent, RecordInfo recordInfo, String runMeterId) {
        // 用户类型
        String userType = recordInfo.getUserType();

        // 线路
        if (UserCategoryConstant.LINE.equals(userType)) {
            outageEvent.setObjType("1");
            outageEvent.setObjId(recordInfo.getLineNo());
            outageEvent.setObjName(recordInfo.getLineName());
            return;
        }

        // 公变台区
        if (UserCategoryConstant.PUBLIC_TA.equals(userType)) {
            outageEvent.setObjType("2");
            outageEvent.setObjId(recordInfo.getTaNo());
            outageEvent.setObjName(recordInfo.getTaName());
            return;
        }

        // 专变台区
        if (UserCategoryConstant.isSpecialtyTa(userType)) {
            outageEvent.setObjType("3");
            outageEvent.setObjId(recordInfo.getTaNo());
            outageEvent.setObjName(recordInfo.getTaName());
            return;
        }

        // 分支
        if (UserCategoryConstant.BRANCH.equals(userType)) {
            outageEvent.setObjType("4");
            outageEvent.setObjId(recordInfo.getBranchNo());
            outageEvent.setObjName(recordInfo.getBranchName());
            return;
        }

        // 低压用户
        if (UserCategoryConstant.LOW_USER.equals(userType)) {
            outageEvent.setObjType("5");
            outageEvent.setObjId(recordInfo.getElecCustNo());
            outageEvent.setObjName(recordInfo.getElecCustName());
            return;
        }

        // 未知对象类型，用户电能表标识作为objId, 用户类型作为对象类型
        outageEvent.setObjId(runMeterId);
        outageEvent.setObjType(userType);
    }


    /**
     * 更新停电事件为复电
     *
     * @param recordInfo    档案信息
     * @param outageEndTime 停电结束时间
     * @param taNo          台区编号
     * @param startTime     复电数据接收时间
     * @Param restoreSource 复电来源（1-告警流研判，2-告警批研判，3-计划工单，4-故障工单，5-电压采集）
     */
    @Override
    public void updateOutageEvent(RecordInfo recordInfo, String outageEndTime, String taNo, List<String> runMeterIds, String restoreSource, Long startTime) {
        // 根据档案信息获取对象编号
        String objId = getObjIdByRecordInfo(recordInfo);
        // 更新事件表
        // mkPrPfOutageEventDetailDao.recover(objId, outageEndTime, restoreSource, startTime);

        // 更新 实时停复电 表中的数据为复电
        outageEndTime = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(DateUtil.parse(outageEndTime, "yyyyMMddHHmmss"));
        String runMeterId = recordInfo.getRunMeterId();
        // 若台区编号有值，则更新整个台区为复电
        if (taNo != null) {
            runMeterId = null;
        }

        // 更新复电时间与复电状态
        outageRecoveryMonDao.recover(runMeterId, runMeterIds, taNo, null, outageEndTime, restoreSource, startTime);

        // 查询出刚刚更新的数据，推送到datahub
        List<MkPrPfOutageRecoveryMonVO> voList = outageRecoveryMonDao.getRecoverData(runMeterId, taNo, startTime);
        // pushKafka(voList, runMeterId, taNo, startTime);
    }


    /**
     * 推送复电事件到kafka
     *
     * @param voList     推送对象列表
     * @param runMeterId 运行电能表标识
     * @param taNo       台区编号
     * @param startTime  复电数据接收时间
     */
    // public void pushKafka(List<MkPrPfOutageRecoveryMonVO> voList, String runMeterId, String taNo, Long startTime) {
    //     String restorePushFailReason = sendDatahub.sendToOutageMon(voList);
    //     String restorePushStatus = "1";
    //     if (restorePushFailReason != null) {
    //         // 推送失败原因不为空则为推送失败
    //         restorePushStatus = "2";
    //     }
    //     outageRecoveryMonDao.updateRecoveryMonDao(runMeterId, taNo, startTime, restorePushStatus, restorePushFailReason);
    //
    //
    //     // for (MkPrPfOutageRecoveryMonVO vo : voList) {
    //     //     // 只推送已验收台区
    //     //     if ("1".equals(vo.getTaAcceptStatus())) {
    //     //         // 推送到kafka
    //     //         String value = JsonUtil.toJson(vo);
    //     //         ProducerRecord<String, String> producerRecord = new ProducerRecord<>("TMR_GD_TFDGJ_03_syy", value);
    //     //         kafkaProducer.send(producerRecord,
    //     //                 // 推送结果回调
    //     //                 (recordMetadata, e) -> {
    //     //                     // 复电推送状态 （1-成功， 2-失败）
    //     //                     String restorePushStatus = "1";
    //     //                     // 失败原因
    //     //                     String restorePushFailReason = null;
    //     //                     if (recordMetadata == null) {
    //     //                         // recordMetadata位空则标识推送失败
    //     //                         restorePushStatus = "2";
    //     //                         restorePushFailReason = e.getMessage();
    //     //                     }
    //     //                     // 更新复电推送状态与推送时间
    //     //                     outageRecoveryMonDao.updateRestorePushTime(vo.getObjId(), vo.getOutageEventId(), vo.getRunMeterId(), restorePushStatus, restorePushFailReason);
    //     //                 }
    //     //         );
    //     //     }
    //     // }
    // }


    /**
     * 获取objId
     *
     * @param recordInfo 档案信息
     * @return objId
     */
    private String getObjIdByRecordInfo(RecordInfo recordInfo) {
        // 用户类型
        String userType = recordInfo.getUserType();

        // 线路
        if (UserCategoryConstant.LINE.equals(userType)) {
            return recordInfo.getLineNo();
        }

        // 公变台区 / 专变台区
        if (UserCategoryConstant.PUBLIC_TA.equals(userType) || UserCategoryConstant.isSpecialtyTa(userType)) {
            return recordInfo.getTaNo();
        }

        // 分支
        if (UserCategoryConstant.BRANCH.equals(userType)) {
            return recordInfo.getBranchNo();
        }

        // 低压用户
        if (UserCategoryConstant.LOW_USER.equals(userType)) {
            return recordInfo.getElecCustNo();
        }
        return null;
    }

}
